package com.zhangxun.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zhangxun.domain.Basket;
import com.zhangxun.domain.Prod;
import com.zhangxun.domain.Sku;
import com.zhangxun.feign.BasketProdFeign;
import com.zhangxun.service.BasketService;
import com.zhangxun.mapper.BasketMapper;
import com.zhangxun.util.SecurityUtil;
import com.zhangxun.vo.CartItem;
import com.zhangxun.vo.CartMoney;
import com.zhangxun.vo.CartVo;
import com.zhangxun.vo.ShopCart;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.temporal.ValueRange;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
* @author 张循
* @description 针对表【basket(购物车)】的数据库操作Service实现
* @createDate 2023-01-07 16:55:01
*/
@Service
public class BasketServiceImpl extends ServiceImpl<BasketMapper, Basket>
    implements BasketService{

    @Autowired
    private BasketProdFeign basketProdFeign;

    @Autowired
    private BasketMapper basketMapper;

    /**
     * 查询购物车商品详情的方法
     * @return
     */
    @Override
    public CartVo selectInfo() {
        CartVo cartVo = new CartVo();
        //获取购物车中商品集合
        List<Basket> basketList = basketMapper.selectList(new LambdaQueryWrapper<Basket>()
                .eq(Basket::getUserId, SecurityUtil.getWxUserId()));

        //判断购物车中是否有商品
        if(CollectionUtil.isNotEmpty(basketList)){//有商品
            //将商品以店铺id分组成map
            Map<Long, List<Basket>> shopMap = basketList.stream().collect(Collectors.groupingBy(Basket::getSkuId));


            //获取商品id集合，和skuId集合
            List<Long> prodIdList = basketList.stream().map(Basket::getProdId).collect(Collectors.toList());
            List<Long> skuIdList = basketList.stream().map(Basket::getSkuId).collect(Collectors.toList());
            //通过远程调用查询商品和sku
            List<Prod> prodList = basketProdFeign.loadProdByIds(prodIdList);
            List<Sku> skuList = basketProdFeign.loadSkuByIds(skuIdList);

            //将商品和sku的list转化成map
            Map<Long, Prod> prodMap = prodList.stream().collect(Collectors.toMap(Prod::getProdId, prod -> prod));
            Map<Long, Sku> skuMap = skuList.stream().collect(Collectors.toMap(Sku::getSkuId, sku -> sku));

            //创建商店集合
            List<ShopCart> shopCartList = new LinkedList<>();
            //遍历商店id为key的mao
            shopMap.forEach((shopId,list)->{
                //创建一个商店
                ShopCart shopCart = new ShopCart();
                List<CartItem> cartItemList = list.stream().map(basket -> {
                    CartItem cartItem = new CartItem();
                    Prod prod = prodMap.get(basket.getProdId());
                    Sku sku = skuMap.get(basket.getSkuId());
                    BeanUtils.copyProperties(prod,cartItem);
                    BeanUtils.copyProperties(sku,cartItem);
                    BeanUtils.copyProperties(basket,cartItem);
                    return cartItem;
                }).collect(Collectors.toList());
                shopCart.setShopCartItems(cartItemList);
                //todo 设置店铺优惠卷
                shopCartList.add(shopCart);
            });

          cartVo.setShopCarts(shopCartList);
          //todo 设置平台优惠卷
        }

        return cartVo;
    }

    /**
     * 添加商品到购物车或者修改购物车商品数量的方法
     * @param basket
     * @return
     */
    @Override
    public Boolean saveOrUpdateBasket(Basket basket) {
        Boolean result = null;
        Basket selectBasket = basketMapper.selectOne(new LambdaQueryWrapper<Basket>()
                .eq(Basket::getUserId, SecurityUtil.getWxUserId())
                .eq(Basket::getSkuId, basket.getSkuId())
                .eq(Basket::getProdId, basket.getProdId()));
        if(ObjectUtil.isNotNull(selectBasket)){
            selectBasket.setBasketCount(selectBasket.getBasketCount()+basket.getBasketCount());
           return  baseMapper.updateById(selectBasket) == 1;
        }

        basket.setUserId(SecurityUtil.getWxUserId());
        basket.setBasketDate(new Date());

        return baseMapper.insert(basket) == 1;

    }

    /**
     * 计算商品总价,优惠之后的价格等
     *
     * 优惠金额，慢100减10块，最多减200.
     * 慢90面运费，不满90，收8块运费
     * @param basketIds 要计算的购物车的id
     * @return
     */
    @Override
    public CartMoney totalPay(List<Long> basketIds) {

        //创建对象用来接收数据
        CartMoney cartMoney = new CartMoney();
        if(CollectionUtil.isEmpty(basketIds)){
            return cartMoney;
        }

        //获取到所有购物车对象
        List<Basket> basketList = baseMapper.selectBatchIds(basketIds);
        //获取skuid集合
        List<Long> skuIdList = basketList.stream().map(Basket::getSkuId).collect(Collectors.toList());
        //根据skuid查询sku，sku当中包含了商品的单价
        List<Sku> skuList = basketProdFeign.loadSkuByIds(skuIdList);
        //转换成map方便通过skuid获取sku对象
        Map<Long, Sku> skuMap = skuList.stream().collect(Collectors.toMap(Sku::getSkuId,sku->sku));
        //转换成每个basekt的总价集合
        List<BigDecimal> totalMoneyList = basketList.stream().map(basket -> {
            Sku sku = skuMap.get(basket.getSkuId());
            BigDecimal multiply = sku.getPrice().multiply(new BigDecimal(basket.getBasketCount()));

            return multiply;
        }).collect(Collectors.toList());

        //计算商品总价总价
        BigDecimal totalMoney = totalMoneyList.stream().reduce(BigDecimal::add).get();
        //计算优惠金额
        int num = totalMoney.intValue() / 100;
        BigDecimal subtractMoney = new BigDecimal(num*10>200? 200: num*10);
        //计算运费
        BigDecimal transMoney = new BigDecimal(totalMoney.intValue()>=90?0:8);

        //封装数据返回
        //设置总价
        cartMoney.setTotalMoney(totalMoney);
        //设置优惠金额
        cartMoney.setSubtractMoney(subtractMoney);
        //设置最终金额为总金额减去优惠加上运费
        cartMoney.setFinalMoney(totalMoney.subtract(subtractMoney).add(transMoney));
        //设置运费
        cartMoney.setTransMoney(transMoney);

        return cartMoney;
    }
}




